from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, status, Query, UploadFile, File
from sqlalchemy.orm import Session

from app.core.database.connection import get_database
from app.domains.work_order.services import WorkOrderService
from app.domains.work_order.schemas import (
    WorkOrderCreate, WorkOrderUpdate, WorkOrderResponse, WorkOrderDetailResponse,
    WorkOrderListQuery, WorkOrderAssign, WorkOrderStatusUpdate, WorkOrderComment,
    WorkOrderCommentResponse, WorkOrderBatchOperation, WorkOrderStatistics
)
from app.shared.schemas.response import success_response, paginated_response, error_response
from app.shared.exceptions.base import ValidationException, BusinessException, NotFoundException
from app.shared.constants.status_codes import BusinessCode
from app.api.dependencies import get_current_user, require_roles, check_resource_permission, ResourcePermission
from app.shared.constants.enums import UserRole, WorkOrderStatus
import logging

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/work-orders", tags=["工单管理"])


@router.post("", response_model=dict, summary="创建工单")
async def create_work_order(
    work_order_data: WorkOrderCreate,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    创建工单（所有用户可操作）
    
    - **title**: 工单标题
    - **description**: 问题描述（可选）
    - **device_id**: 设备ID
    - **priority**: 优先级（low/medium/high/urgent）
    - **work_order_type**: 工单类型（maintenance/repair/inspection/installation/cleaning）
    - **location**: 位置（可选）
    - **estimated_duration**: 预计处理时长（可选）
    - **required_skills**: 所需技能（可选）
    - **materials_needed**: 所需物料（可选）
    """
    try:
        work_order_service = WorkOrderService(db)
        work_order = work_order_service.create_work_order(work_order_data, current_user['id'])
        
        logger.info(f"✅ 工单创建成功: {work_order.work_order_number} by {current_user['username']}")
        
        return success_response(
            data=WorkOrderResponse.from_orm(work_order).dict(),
            message="工单创建成功"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 创建工单异常: {e}")
        return error_response(
            message="创建工单失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("", response_model=dict, summary="获取工单列表")
async def get_work_order_list(
    query: WorkOrderListQuery = Depends(),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取工单列表（所有用户可查看）
    
    - **page**: 页码（默认1）
    - **page_size**: 每页数量（默认20，最大100）
    - **search**: 搜索关键词（工单编号、标题、设备编码）
    - **status**: 工单状态筛选
    - **priority**: 优先级筛选
    - **work_order_type**: 工单类型筛选
    - **assignee_id**: 指派人员ID筛选
    - **reporter_id**: 报告人ID筛选
    - **device_id**: 设备ID筛选
    - **location**: 位置筛选
    - **start_date**: 开始日期
    - **end_date**: 结束日期
    - **overdue_only**: 仅显示过期工单
    - **sort_by**: 排序字段（默认created_at）
    - **sort_order**: 排序方向（asc/desc，默认desc）
    """
    try:
        work_order_service = WorkOrderService(db)
        
        # 普通用户只能查看自己相关的工单
        if current_user['role'] == UserRole.USER.value:
            query.reporter_id = current_user['id']
        elif current_user['role'] == UserRole.TECHNICIAN.value:
            # 技术员可以查看分配给自己的工单和自己创建的工单
            if not query.assignee_id and not query.reporter_id:
                # 如果没有指定筛选条件，显示相关的工单
                pass
        
        work_orders, total = work_order_service.get_work_order_list(query)
        
        # 转换为响应格式
        work_order_list = []
        for work_order in work_orders:
            work_order_dict = WorkOrderResponse.from_orm(work_order).dict()
            # 添加关联信息
            if work_order.device:
                work_order_dict['device_code'] = work_order.device.device_code
                work_order_dict['device_name'] = work_order.device.device_name
            if work_order.reporter:
                work_order_dict['reporter_name'] = work_order.reporter.username
            if work_order.assignee:
                work_order_dict['assignee_name'] = work_order.assignee.username
            work_order_list.append(work_order_dict)
        
        return paginated_response(
            items=work_order_list,
            total=total,
            page=query.page,
            page_size=query.page_size,
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取工单列表异常: {e}")
        return error_response(
            message="获取工单列表失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("/{work_order_id}", response_model=dict, summary="获取工单详情")
async def get_work_order_detail(
    work_order_id: int,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取工单详细信息
    """
    try:
        work_order_service = WorkOrderService(db)
        detail_data = work_order_service.get_work_order_detail(work_order_id)
        
        work_order = detail_data["work_order"]
        
        # 权限检查：普通用户只能查看自己相关的工单
        if (current_user['role'] == UserRole.USER.value and 
            work_order.reporter_id != current_user['id'] and 
            work_order.assignee_id != current_user['id']):
            return error_response(
                message="无权限查看该工单",
                code=BusinessCode.PERMISSION_DENIED
            )
        
        work_order_detail = WorkOrderDetailResponse.from_orm(work_order)
        
        # 添加关联信息
        if work_order.device:
            work_order_detail.device_code = work_order.device.device_code
            work_order_detail.device_name = work_order.device.device_name
        if work_order.reporter:
            work_order_detail.reporter_name = work_order.reporter.username
        if work_order.assignee:
            work_order_detail.assignee_name = work_order.assignee.username
        
        # 添加评论和附件
        work_order_detail.comments = [
            WorkOrderCommentResponse.from_orm(comment).dict() 
            for comment in detail_data["comments"]
        ]
        work_order_detail.attachments = [
            {
                'id': att.id,
                'file_name': att.file_name,
                'file_size': att.file_size,
                'file_type': att.file_type,
                'uploaded_at': att.uploaded_at
            }
            for att in detail_data["attachments"]
        ]
        
        return success_response(
            data=work_order_detail.dict(),
            message="查询成功"
        )
        
    except NotFoundException:
        return error_response(
            message="工单不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except Exception as e:
        logger.error(f"❌ 获取工单详情异常: {e}")
        return error_response(
            message="获取工单详情失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.put("/{work_order_id}", response_model=dict, summary="更新工单信息")
async def update_work_order(
    work_order_id: int,
    work_order_data: WorkOrderUpdate,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    更新工单信息（创建人或管理员可操作）
    
    - **title**: 工单标题
    - **description**: 问题描述
    - **priority**: 优先级
    - **estimated_duration**: 预计处理时长
    - **required_skills**: 所需技能
    - **materials_needed**: 所需物料
    """
    try:
        work_order_service = WorkOrderService(db)
        work_order = work_order_service.get_work_order_by_id(work_order_id)
        
        # 权限检查：只有创建人或管理员可以修改
        if (current_user['role'] not in [UserRole.ADMIN.value, UserRole.MANAGER.value] and
            work_order.reporter_id != current_user['id']):
            return error_response(
                message="无权限修改该工单",
                code=BusinessCode.PERMISSION_DENIED
            )
        
        updated_work_order = work_order_service.update_work_order(work_order_id, work_order_data)
        
        logger.info(f"✅ 工单信息更新成功: {updated_work_order.work_order_number} by {current_user['username']}")
        
        return success_response(
            data=WorkOrderResponse.from_orm(updated_work_order).dict(),
            message="工单信息更新成功"
        )
        
    except NotFoundException:
        return error_response(
            message="工单不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 更新工单信息异常: {e}")
        return error_response(
            message="更新工单信息失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/{work_order_id}/assign", response_model=dict, summary="分配工单")
async def assign_work_order(
    work_order_id: int,
    assign_data: WorkOrderAssign,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_work_orders, "无权限分配工单"
    )),
    db: Session = Depends(get_database)
):
    """
    分配工单（经理和管理员可操作）
    
    - **assignee_id**: 指派人员ID
    - **notes**: 分配备注（可选）
    - **due_date**: 截止时间（可选）
    """
    try:
        work_order_service = WorkOrderService(db)
        assigned_work_order = work_order_service.assign_work_order(work_order_id, assign_data)
        
        logger.info(f"✅ 工单分配成功: {assigned_work_order.work_order_number} -> 用户ID {assign_data.assignee_id} by {current_user['username']}")
        
        return success_response(
            data=WorkOrderResponse.from_orm(assigned_work_order).dict(),
            message="工单分配成功"
        )
        
    except NotFoundException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.DATA_NOT_FOUND
        )
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 分配工单异常: {e}")
        return error_response(
            message="分配工单失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.patch("/{work_order_id}/status", response_model=dict, summary="更新工单状态")
async def update_work_order_status(
    work_order_id: int,
    status_data: WorkOrderStatusUpdate,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    更新工单状态（指派人员或管理员可操作）
    
    - **status**: 工单状态
    - **notes**: 状态更新备注（可选）
    - **completion_notes**: 完成备注（状态为完成时）
    - **actual_duration**: 实际处理时长（状态为完成时）
    - **materials_used**: 使用物料（状态为完成时）
    """
    try:
        work_order_service = WorkOrderService(db)
        updated_work_order = work_order_service.update_work_order_status(
            work_order_id, status_data, current_user['id']
        )
        
        logger.info(f"✅ 工单状态更新: {updated_work_order.work_order_number} -> {status_data.status} by {current_user['username']}")
        
        return success_response(
            data=WorkOrderResponse.from_orm(updated_work_order).dict(),
            message="工单状态更新成功"
        )
        
    except NotFoundException:
        return error_response(
            message="工单不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 更新工单状态异常: {e}")
        return error_response(
            message="更新工单状态失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/{work_order_id}/comments", response_model=dict, summary="添加工单评论")
async def add_work_order_comment(
    work_order_id: int,
    comment_data: WorkOrderComment,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    添加工单评论（相关用户可操作）
    
    - **content**: 评论内容
    - **is_internal**: 是否内部评论
    """
    try:
        work_order_service = WorkOrderService(db)
        comment = work_order_service.add_comment(work_order_id, comment_data, current_user['id'])
        
        logger.info(f"✅ 工单评论添加成功: 工单ID {work_order_id} by {current_user['username']}")
        
        return success_response(
            data=WorkOrderCommentResponse.from_orm(comment).dict(),
            message="评论添加成功"
        )
        
    except NotFoundException:
        return error_response(
            message="工单不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except Exception as e:
        logger.error(f"❌ 添加工单评论异常: {e}")
        return error_response(
            message="添加评论失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/batch-operation", response_model=dict, summary="批量操作工单")
async def batch_operation(
    operation_data: WorkOrderBatchOperation,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_work_orders, "无权限批量操作工单"
    )),
    db: Session = Depends(get_database)
):
    """
    批量操作工单（经理和管理员可操作）
    
    - **work_order_ids**: 工单ID列表
    - **operation**: 操作类型 (assign, update_status, delete)
    - **params**: 操作参数
    
    支持的批量操作：
    - assign: 批量分配 (params: {assignee_id: int})
    - update_status: 批量更新状态 (params: {status: "pending/assigned/in_progress/completed/cancelled", notes: str})
    - delete: 批量删除工单（仅待处理状态）
    """
    try:
        work_order_service = WorkOrderService(db)
        results = work_order_service.batch_operation(operation_data, current_user['id'])
        
        logger.info(
            f"✅ 批量操作完成: {operation_data.operation}, "
            f"成功 {len(results['success'])}, 失败 {len(results['failed'])} "
            f"by {current_user['username']}"
        )
        
        return success_response(
            data=results,
            message=f"批量操作完成，成功 {len(results['success'])} 个，失败 {len(results['failed'])} 个"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 批量操作异常: {e}")
        return error_response(
            message="批量操作失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.delete("/{work_order_id}", response_model=dict, summary="删除工单")
async def delete_work_order(
    work_order_id: int,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_work_orders, "无权限删除工单"
    )),
    db: Session = Depends(get_database)
):
    """
    删除工单（经理和管理员可操作）
    
    注意：只能删除待处理状态的工单
    """
    try:
        work_order_service = WorkOrderService(db)
        
        # 获取工单信息用于日志
        work_order = work_order_service.get_work_order_by_id(work_order_id)
        
        success = work_order_service.delete_work_order(work_order_id)
        
        if success:
            logger.info(f"✅ 工单删除成功: {work_order.work_order_number} by {current_user['username']}")
            return success_response(message="工单删除成功")
        else:
            return error_response(
                message="工单删除失败",
                code=BusinessCode.OPERATION_FAILED
            )
        
    except NotFoundException:
        return error_response(
            message="工单不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 删除工单异常: {e}")
        return error_response(
            message="删除工单失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("/statistics/dashboard", response_model=dict, summary="获取工单仪表盘统计")
async def get_dashboard_statistics(
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_view_reports, "无权限查看统计报表"
    )),
    db: Session = Depends(get_database)
):
    """
    获取工单仪表盘统计数据（经理和管理员可查看）
    """
    try:
        work_order_service = WorkOrderService(db)
        stats = work_order_service.get_statistics()
        
        return success_response(
            data=stats,
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取仪表盘统计异常: {e}")
        return error_response(
            message="获取统计数据失败",
            code=BusinessCode.OPERATION_FAILED
        )